<?php
	
$address = "127.0.0.1";
$port = 9999; //调试的时候，可以多换端口来测试程序！
 
set_time_limit(0); 
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_block($sock);
socket_bind($sock, $address, $port);
socket_listen($sock, 4);
 
 
do
{
    echo "Waiting for Connection...\n";
    $msgsock = socket_accept($sock);
    echo "Waiting for Request...\n";
    $buf = socket_read($msgsock, 8192);     //读取请求
    echo "Request Received: $buf\n";
    $response = hand_shake($buf);
    socket_write($msgsock,$response,strlen($response)); //发送响应
 
    //正式开始通信...
    $buf = socket_read($msgsock, 8192); //获取前端发送的消息
 
    //这里我用了③中的编码和解码方法mask和umaske，原来的无法正确的接收到客户端发的信息，乱码，
    //而且无法将json数据编码发送给前端，我是没成功。
    if (unmask($buf) == 'getPeerInfo') {
                //我要返回的json数据
     		   	$msg = '[{
		            "Addr": "/ip4/95.179.192.99/tcp/10001",
		            "Peer": "QmQFy5XWmtZ7U2nZu198qYW8LefvrBK3Y9b3V1MqUfuoRT",
		            "Latency": "",
		            "Muxer": "你好",
		            "Direction": 0,
		            "Streams": null
		        },
		        {
		            "Addr": "/ip4/95.216.192.206/tcp/4001",
		            "Peer": "QmZyVchYnNcRdCcikT29GNFGZscBdWeJ6BaWdTxZmm2V5M",
		            "Latency": "",
		            "Muxer": "你好",
		            "Direction": 0,
		            "Streams": null
		        },
		        {
		            "Addr": "/ip4/98.11.199.27/tcp/39853",
		            "Peer": "QmVvP46C4wqyKt4aGBsf9gsr482rnf65ZxP1Hh8v4xPgdD",
		            "Latency": "",
		            "Muxer": "",
		            "Direction": 0,
		            "Streams": null
		        },
		        {
		            "Addr": "/ipfs/QmRv1GNseNP/p2p-circuit",
		            "Peer": "QmVCgCcoeB9fqoat8jJS8XDxqEnVizNzTbz8JsM2NCUZcY",
		            "Latency": "",
		            "Muxer": "",
		            "Direction": 0,
		            "Streams": null
		        },
		        {
		            "Addr": "/ipfs/QmRv1GNseNP/p2p-circuit",
		            "Peer": "QmSEzrFkZQCN138uTHeJaBBH2GQ3Kq3XnUAx2iAMneTQsZ",
		            "Latency": "",
		            "Muxer": "",
		            "Direction": 0,
		            "Streams": null
		        }]';
    		$response_text = mask(json_encode($msg));  
    		socket_write($msgsock, $response_text, strlen($response_text));
     }else{
            //这里不建议用array，因为json_encode之后出现空值，可能是编码问题。
            //一旦编码出问题，就是返回空，又不报错
     		$msg = '{"error:"Invalid method"}';   
     		$response_text = mask(json_encode($msg));
    		socket_write($msgsock, $response_text, strlen($response_text));
     };
     socket_close($msgsock);
} while (true);
socket_close($sock);
 
function hand_shake($buf){
    $buf  = substr($buf,strpos($buf,'Sec-WebSocket-Key:')+18);
    $key  = trim(substr($buf,0,strpos($buf,"\r\n")));
 
    $new_key = base64_encode(sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
 
    $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
    $new_message .= "Upgrade: websocket\r\n";
    $new_message .= "Sec-WebSocket-Version: 13\r\n";
    $new_message .= "Connection: Upgrade\r\n";
    $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
    return $new_message;
}
 
 
//解码数据
function unmask($text) {
    $length = ord($text[1]) & 127;
    if($length == 126) {
        $masks = substr($text, 4, 4);
        $data = substr($text, 8);
    }
    elseif($length == 127) {
        $masks = substr($text, 10, 4);
        $data = substr($text, 14);
    }
    else {
        $masks = substr($text, 2, 4);
        $data = substr($text, 6);
    }
    $text = "";
    for ($i = 0; $i < strlen($data); ++$i) {
        $text .= $data[$i] ^ $masks[$i%4];
    }
    return $text;
}
 
//function code($msg){
//     $msg = preg_replace(array('/\r$/','/\n$/','/\r\n$/',), '', $msg);
//     $frame = array();
//     $frame[0] = '81';
//     $len = strlen($msg);
//     $frame[1] = $len<16?'0'.dechex($len):dechex($len);
//     $frame[2] = ord_hex($msg);
//     $data = implode('',$frame);
//     return pack("H*", $data);
// }
 
function mask($text)
{
    $b1 = 0x80 | (0x1 & 0x0f);
    $length = strlen($text);
    
    if($length <= 125)
        $header = pack('CC', $b1, $length);
    elseif($length > 125 && $length < 65536)
        $header = pack('CCn', $b1, 126, $length);
    elseif($length >= 65536)
        $header = pack('CCNN', $b1, 127, $length);
    return $header.$text;
}
 
//function ord_hex($data)  {
//    $msg = '';
//    $l = strlen($data);
//    for ($i= 0; $i<$l; $i++) {
//        $msg .= dechex(ord($data{$i}));
//    }
//    return $msg;
//}
 
?>
